package org.xlp.auto.create;

import org.xlp.assertion.AssertUtils;
import org.xlp.auto.create.exception.AutoCreatorDataLoseException;
import org.xlp.auto.create.util.AutoCreatorUtils;
import org.xlp.utils.XLPStringUtil;

/**
 * Description: ServiceImpl java文件自动创建类
 * <br/>date: 2023/12/04 11:05
 *
 * @version 1.0
 * @author: xlp
 */
public class ServiceImplAutoCreator extends AbstractAutoCreator{
    private ServiceAutoCreator serviceAutoCreator;

    /**
     * 标记是否关联相应的实体相关操作，默认不关联
     */
    private boolean relationEntity = false;

    /**
     * 存储对应接口名称
     */
    private String serviceName;

    public ServiceImplAutoCreator(){
        setSubPackageName(Constants.SERVICE_SUB_PACKAGE_NAME + ".impl");
    }

    /**
     * 构造函数
     * @param entityName
     * @throws NullPointerException 假如参数为null，则抛出该异常
     */
    public ServiceImplAutoCreator(String entityName) {
        this();
        setEntityName(entityName);
        String subPkgName = Constants.SERVICE_SUB_PACKAGE_NAME + "." + entityName.toLowerCase() + ".impl";
        setSubPackageName(subPkgName);
        this.relationEntity = true;
    }

    /**
     * 构造函数
     * @param serviceAutoCreator
     * @throws NullPointerException 假如参数为null，则抛出该异常
     */
    public ServiceImplAutoCreator(ServiceAutoCreator serviceAutoCreator) {
        AssertUtils.isNotNull(serviceAutoCreator, "serviceAutoCreator parameter must not be null!");
        this.serviceAutoCreator = serviceAutoCreator;

        AutoCreatorUtils.autoCreatorConvert(this, serviceAutoCreator);

        String subPkgName = getSubPackageName();
        subPkgName = XLPStringUtil.isEmpty(subPkgName) ? "impl" : subPkgName + ".impl";
        setSubPackageName(subPkgName);
        this.serviceName = getServiceName();
    }

    /**
     * 构造函数
     *
     * @param abstractAutoCreator
     * @throws NullPointerException 假如参数为null，则抛出该异常
     */
    public ServiceImplAutoCreator(AbstractAutoCreator abstractAutoCreator) {
        super(abstractAutoCreator);
        String subPkgName = Constants.SERVICE_SUB_PACKAGE_NAME + "." +
                abstractAutoCreator.getEntityName().toLowerCase() + ".impl";
        setSubPackageName(subPkgName);
        this.relationEntity = true;
    }

    @Override
    public String[] getInterfaceNames() {
        String[] interfaceNames = super.getInterfaceNames();
        if ((serviceAutoCreator == null || serviceAutoCreator.getClassType() != ClassType.INTERFACE)
            && !relationEntity) {
            return interfaceNames;
        }

        String interfaceName = XLPStringUtil.isEmpty(serviceName) && relationEntity ?
                getEntityName().toLowerCase() + "Service" : serviceName;
        this.addInterfaceName(interfaceName);

        return super.getInterfaceNames();
    }

    private String getServiceName(){
        if (serviceAutoCreator != null) {
            try {
                return serviceAutoCreator.getFileName().replace(Constants.JAVA_FILE_SUFFIX, "");
            } catch (AutoCreatorDataLoseException ignored) {
            }
        }
        return null;
    }

    @Override
    public String getSupperClassName() {
        String supperClassName = super.getSupperClassName();
        supperClassName = (XLPStringUtil.isEmpty(supperClassName) && serviceAutoCreator != null
                && serviceAutoCreator.getClassType() != ClassType.INTERFACE && !relationEntity)
                ? serviceName : supperClassName;
        return supperClassName;
    }

    /**
     * Java文件导入包内容
     *
     * @return
     */
    @Override
    protected String makeImportContent() {
        String importContent = "import org.xlp.mvc.annotation.Service;\n";

        String basePackage = getRootPackageName();
        basePackage = XLPStringUtil.isEmpty(basePackage) ? XLPStringUtil.EMPTY : basePackage.trim() + ".";

        String packageName = StringUtils.getFullPackageName(serviceAutoCreator);
        if (!XLPStringUtil.isEmpty(packageName)){
            importContent += "import " + packageName + "." + serviceName + ";\n";
        } else if(relationEntity){
            String name = basePackage + Constants.SERVICE_SUB_PACKAGE_NAME + "." + getEntityName().toLowerCase()
                    + "." + getEntityName() + "Service";
            importContent += "import " + name + ";\n";

            name = basePackage + Constants.DAO_SUB_PACKAGE_NAME + "." + getEntityName().toLowerCase()
                    + "." + getEntityName() + "Dao";
            importContent += "import " + name + ";\n";

            importContent += "import org.xlp.bean.annotation.AutoFill;\n";
        }
        // 导入包
        return importContent;
    }

    /**
     * java文件注解类容
     *
     * @return
     */
    @Override
    protected String makeAnnotationContent() {
        if (XLPStringUtil.isEmpty(serviceName) && !relationEntity){
            return "@Service\n";
        }
        if (!XLPStringUtil.isEmpty(serviceName)) {
            return "@Service(id = \"" + StringUtils.firstCharToLowerCase(serviceName) + "\")\n";
        }
        return "@Service(id = \"" + StringUtils.firstCharToLowerCase(getEntityName()) + "Service\")\n";
    }

    /**
     * 获取java文件名称
     *
     * @return
     * @throws AutoCreatorDataLoseException 假如获取失败，则抛出该异常
     */
    @Override
    protected String getFileName() throws AutoCreatorDataLoseException {
        if (XLPStringUtil.isEmpty(getEntityName())){
            throw new AutoCreatorDataLoseException("实体名称未设置。");
        }
        return getEntityName() + "ServiceImpl" + Constants.JAVA_FILE_SUFFIX;
    }

    /**
     * java文件对应的类主体内容
     *
     * @return
     */
    @Override
    protected String makeBodyContent() {
        StringBuilder sb = new StringBuilder();
        if (relationEntity) {
            String dao = getEntityName() + "Dao";
            String daoVar = StringUtils.firstCharToLowerCase(dao);
            sb.append("\t@AutoFill\n");
            sb.append("\tprivate ").append(dao).append(" ").append(daoVar).append(";\n");
            sb.append("\n");
            sb.append("\tpublic void set").append(dao).append("(")
                    .append(dao).append(" ").append(daoVar).append(") {\n");
            sb.append("\t\tthis.").append(daoVar).append(" = ").append(daoVar).append(";\n");
            sb.append("\t}\n");
        }
        return sb.length() == 0 ? super.makeBodyContent() : sb.toString();
    }
}
